home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / music4c.sit / Music4C Folder / SFConvert folder / SFConvertFile.c < prev    next >
Text File  |  1990-06-26  |  21KB  |  763 lines

  1.  
  2.  
  3. #include    "SFConvert.h"
  4. #include    "SDtype.h"
  5. #include    <stdio.h>
  6. #include    <string.h>
  7. #include    <unix.h>
  8.  
  9.  
  10. Boolean    OpenSFWrite(void);
  11. Boolean    SetSFDir(Str255, long *);
  12. Boolean    GetSFDir(Str255 *);
  13. Boolean    CloseSF(void);
  14. Boolean    updateNewSFResFile(void);
  15.  
  16.  
  17. Boolean    OpenSFRead(void);
  18.  
  19. extern    void  GetMusic4C_Prefs(void);
  20.  
  21. extern    void    OSError2(Str255, Str255, OSErr);
  22. extern    void    OSError(Str255, Str255);
  23. extern    void    PstringCopy(char *, char *);
  24. extern    void    PstringCat(char *, char *);
  25. extern    void    DoOSErrorAlert(Str255, Str255);
  26.  
  27.  
  28.  
  29.  
  30. SFReply        SoundFileReply;
  31. SFReply        NewSoundFileReply;
  32. WDPBRec        myWDParamBlk;
  33. Point        where;
  34. FileParam    fPB;
  35. extern        long            SoundFileDirID;
  36. extern        long            StartUpDirID;
  37. extern        int                SFSaveVRef;
  38. extern        OSErr        theErr;
  39.  
  40.  
  41. Boolean    OpenSFWrite()
  42. {
  43.     SFTypeList    types;
  44.     extern        ioParam        myIOParmBlk;
  45.     extern        ioParam        NewParmBlk;
  46.     extern        Str255        SoundFileName;
  47.     extern        Str255        NewSoundFileName;
  48.     extern        int            SFOUTPUTtype;
  49.     extern        Str255        SFDirectoryName;
  50.     extern        long            StartUpDirID;
  51.     extern        long            SoundFileDirID;
  52.     extern        long            NumChannels;
  53.     int    c;
  54.  
  55.     if ( SFDirectoryName[0] != NIL ) {
  56.         if ( !SetSFDir(SFDirectoryName, &SoundFileDirID) ) {
  57.             CurDirStore = StartUpDirID;
  58.             return(FALSE);
  59.         }
  60.     }
  61.     
  62.     /* we know number of channels by now, for FLOATS anyway */
  63.     if ( NumChannels >= 2L && SFOUTPUTtype == SD1 )
  64.         SFOUTPUTtype = SD2;
  65.         
  66.     PstringCopy((char *)NewSoundFileName, (char *)SoundFileName);
  67.     PtoCstr((char *)NewSoundFileName);
  68.     c = strcspn((char *)NewSoundFileName,".");
  69.     switch(SFOUTPUTtype) {
  70.         case    INT16:
  71.             strcpy((char *)NewSoundFileName+c, ".INT16");
  72.             break;
  73.         case    AIFF:
  74.             strcpy((char *)NewSoundFileName+c, ".AIF");
  75.             break;
  76.         case    SD1:
  77.             strcpy((char *)NewSoundFileName+c, ".SD");
  78.             break;
  79.         case    SD2:
  80.             strcpy((char *)NewSoundFileName+c, ".SD2");
  81.             break;
  82.         case    FLOAT:
  83.             strcpy((char *)NewSoundFileName+c, ".FLOAT");
  84.             break;
  85.     }
  86.     SetPt(&where, 100, 100);
  87.  
  88.     CtoPstr((char *)NewSoundFileName);
  89.  
  90.  
  91.     SFPutFile(where, "\pSound File name:", &NewSoundFileName, NIL, &NewSoundFileReply);
  92.     if(!NewSoundFileReply.good) {
  93.         return(FALSE);
  94.     }
  95.     GetSFDir(&SFDirectoryName);
  96.     /* we now have the directory where the sound file is to be created */
  97.     SetSFDir(SFDirectoryName, &SoundFileDirID);
  98.     
  99.     PstringCopy((char *)NewSoundFileName, (char *)NewSoundFileReply.fName);
  100.     NewParmBlk.ioNamePtr = (StringPtr)NewSoundFileName;
  101.     NewParmBlk.ioVRefNum = NewSoundFileReply.vRefNum;
  102.     NewParmBlk.ioVersNum = NewSoundFileReply.version;
  103.  
  104.     if ( (theErr = PBCreate(&NewParmBlk, FALSE)) != noErr ) {
  105.         if ( theErr == dupFNErr ) {    /* set logical EOF's to zero */
  106.             NewParmBlk.ioPermssn = fsWrPerm;
  107.             NewParmBlk.ioMisc = (Ptr)NIL;
  108.             theErr = PBOpen(&NewParmBlk, FALSE);
  109.             if ( theErr == opWrErr ) {
  110.                 /* already open, do  nothing */
  111.             }
  112.             else if ( theErr != noErr ) {
  113.                 OSError2("\pError opening sound file: ", NewSoundFileName, theErr);
  114.                 return(FALSE);
  115.             }
  116.             NewParmBlk.ioMisc = (Ptr)1;
  117.             theErr = PBSetEOF(&NewParmBlk, FALSE);
  118.             if ( theErr != noErr ) {
  119.                 OSError2("\pError setting EOF for sound file: ", NewSoundFileName, theErr);
  120.                 return(FALSE);
  121.             }
  122.             theErr = PBClose(&NewParmBlk, FALSE);
  123.             if ( theErr != noErr ) {
  124.                 OSError2("\pError while setting EOF for sound file: ", NewSoundFileName, theErr);
  125.                 return(FALSE);
  126.             }
  127.         
  128.             /* do resource fork */
  129.             NewParmBlk.ioMisc = (Ptr)NIL;
  130.             theErr = PBOpenRF(&NewParmBlk, FALSE);
  131.             if ( theErr != noErr ) {
  132.                 if ( theErr != opWrErr ) {
  133.                     OSError2("\pError opening sound file resource fork: ", SoundFileName, theErr);
  134.                     CurDirStore = StartUpDirID;
  135.                     return(FALSE);
  136.                 }
  137.             }
  138.             theErr = PBSetEOF(&NewParmBlk, FALSE);
  139.             if ( theErr != noErr ) {
  140.                 OSError2("\pError setting EOF for sound file resource fork: ", NewSoundFileName, theErr);
  141.                 return(FALSE);
  142.             }
  143.             /* close resource fork */
  144.             theErr = PBClose(&NewParmBlk, FALSE);
  145.             if ( theErr != noErr ) {
  146.                 OSError2("\pError while setting EOF for sound file: ", NewSoundFileName, theErr);
  147.                 return(FALSE);
  148.             }
  149.             
  150.         }
  151.         else { /* error other than dupFNerr */
  152.             OSError2("\pOpenSFWrite Error creating file: ", NewSoundFileName, theErr);
  153.             return(FALSE);
  154.         }
  155.     }
  156.     else { /* new files only */
  157.     }
  158.  
  159.  
  160.     fPB.ioCompletion = (ProcPtr)NIL;
  161.     fPB.ioNamePtr = NewParmBlk.ioNamePtr;
  162.     fPB.ioVRefNum = NewParmBlk.ioVRefNum;
  163.     fPB.ioFVersNum = NewParmBlk.ioVersNum;
  164.     fPB.ioFDirIndex = NIL;
  165.     theErr = PBGetFInfo(&fPB, FALSE);
  166.     if ( theErr != noErr ) {
  167.         OSError2("\pOpenSFWrite Error getting PBGetFInfo while opening file: ", NewSoundFileName, theErr);
  168.         return(FALSE);
  169.     }
  170.     
  171.     /* set creator */
  172.     fPB.ioFlFndrInfo.fdCreator = 'MU4C';
  173. /*    fPB.ioFlFndrInfo.fdCreator = 'SFIN';  i.e. SFInfo */
  174.     switch(SFOUTPUTtype) {
  175.         case    INT16:
  176.             fPB.ioFlFndrInfo.fdType = 'IL16';
  177.             break;
  178.         case    AIFF:
  179.             fPB.ioFlFndrInfo.fdType = 'AIFF';
  180.             break;
  181.         case    SD1:
  182.             fPB.ioFlFndrInfo.fdType = 'SFIL';
  183.             fPB.ioFlFndrInfo.fdCreator = 'XFER';
  184.             /* check for SD2 file */
  185.             /* fPB.ioFlFndrInfo.fdType = 'Sd2f'; */
  186.             break;
  187.         case    SD2:
  188.             fPB.ioFlFndrInfo.fdType = 'Sd2f';
  189.             fPB.ioFlFndrInfo.fdCreator = 'Sd2a';
  190.             break;
  191.         case    FLOAT:
  192.             fPB.ioFlFndrInfo.fdType = 'TEXT';
  193.             break;
  194.     }
  195.  
  196.     fPB.ioFlFndrInfo.fdFlags = NIL;
  197.     theErr = PBSetFInfo(&fPB, FALSE);
  198.     if ( theErr != noErr ) {
  199.         OSError2("\pOpenSFWrite Error setting PBGetFInfo while opening file: ", NewSoundFileName, theErr);
  200.         return(FALSE);
  201.     }
  202.     PBFlushVol(&fPB, FALSE);
  203.     
  204.     /* now open it */
  205.     NewParmBlk.ioPermssn = fsWrPerm;
  206.     NewParmBlk.ioMisc = (Ptr)0L;
  207.     if ( (theErr = PBOpen(&NewParmBlk, FALSE)) != noErr ) {
  208.         OSError2("\pOpenSFWrite Error opening file: ", NewSoundFileName, theErr);
  209.         return(FALSE);
  210.     }
  211.     return(TRUE);
  212. }
  213.  
  214.  
  215.  
  216.  
  217. Boolean    OpenSFRead()
  218. {
  219.     register    i;
  220.     SFTypeList    types;
  221.     extern        ioParam        myIOParmBlk;
  222.     extern        Str255        SoundFileName;
  223.     extern        long            fileSize;
  224.     extern        int            SoundFileType;
  225.     extern        long            NumChannels;
  226.     extern        double        MaxSample;
  227.     extern        double        MinSample;
  228.     extern        long            SampleRate;
  229.     extern        Boolean        SDnoResource;
  230.     Str255        myStr255;
  231.     long            sfResFileRefNum;
  232.     Str255        resString;
  233.     int    wdRefNum;
  234.     
  235.     Handle            myHndl;
  236.     StringHandle    aString;
  237.     Str255            myString;
  238.     
  239.     
  240.     if ( SFDirectoryName[0] != NIL ) {
  241.         if ( !SetSFDir(SFDirectoryName, &SoundFileDirID) ) {
  242.             CurDirStore = StartUpDirID;
  243.             return(FALSE);
  244.         }
  245.     }
  246.     types[0] = 'TEXT';
  247.     types[1] = 'SFIL';
  248.     types[2] = 'Sd2f';
  249.     types[3] = 'AIFF';
  250.     SetPt(&where, 100, 100);
  251.     SFGetFile(where, NIL, NIL, 4, types, NIL, &SoundFileReply);
  252.     if(!SoundFileReply.good) {
  253.         return(FALSE);
  254.     }
  255.  
  256.     GetSFDir(SFDirectoryName);
  257.     SetSFDir(SFDirectoryName, &SoundFileDirID);
  258.     
  259.     PstringCopy((char *)SoundFileName, (char *)SoundFileReply.fName);
  260.     myIOParmBlk.ioNamePtr = (StringPtr)SoundFileReply.fName;
  261.     myIOParmBlk.ioVRefNum = SoundFileReply.vRefNum;
  262.     myIOParmBlk.ioVersNum = SoundFileReply.version;
  263.  
  264.     myIOParmBlk.ioPermssn = fsRdWrPerm;
  265.     if ( (theErr = PBOpen(&myIOParmBlk, FALSE) )!= noErr) {
  266.         OSError("\pError opening file", NIL);
  267.     }
  268.     myIOParmBlk.ioCompletion = NIL;
  269.     PBGetEOF(&myIOParmBlk, FALSE);
  270.     if ( (fileSize = (long)myIOParmBlk.ioMisc) <= 0 ) {
  271.         OSError("\pfile is empty!", NIL);
  272.         return(FALSE);
  273.     }
  274.     
  275.     
  276.     /* now read the resource part */
  277.     /* first check if it is a Sound Designer file */
  278.     fPB.ioCompletion = (ProcPtr)NIL;
  279.     fPB.ioNamePtr = myIOParmBlk.ioNamePtr;
  280.     fPB.ioVRefNum = myIOParmBlk.ioVRefNum;
  281.     fPB.ioFVersNum = myIOParmBlk.ioVersNum;
  282.     fPB.ioFDirIndex = NIL;
  283.     theErr = PBGetFInfo(&fPB, FALSE);
  284.     if ( (fPB.ioFlFndrInfo.fdType == 'TEXT') &&
  285.             ((fPB.ioFlFndrInfo.fdCreator == 'MU4C') || (fPB.ioFlFndrInfo.fdCreator == 'SFIN')))
  286.         SoundFileType = FLOAT;
  287.     if ( fPB.ioFlFndrInfo.fdType == 'SFIL' )
  288.         SoundFileType = SD1;
  289.     else if ( fPB.ioFlFndrInfo.fdType == 'Sd2f' )
  290.         SoundFileType = SD2;
  291.     else if ( fPB.ioFlFndrInfo.fdType == 'AIFF' ) {
  292.         SoundFileType = AIFF;
  293.         return(TRUE);
  294.     }
  295.  
  296. /* we know the type of file, open the resource fork */
  297.  
  298.     sfResFileRefNum = OpenResFile(SoundFileName);
  299.     SDnoResource = FALSE;
  300.     if ((theErr = ResError()) != noErr) {
  301.         /* no resource fork, not a FLOAT or SD2 file, could be SD1 or AIFF */
  302.         if ( SoundFileType != SD1 && SoundFileType != AIFF) {
  303.             OSError2("\pError opening resource file: ", SoundFileName, theErr);
  304.             return(FALSE);
  305.         }
  306.         else {
  307.             SDnoResource = TRUE;
  308.         }
  309.         return(TRUE);
  310.     }
  311.     
  312.     
  313.     GetIndString(&resString, SFRESOURCENUM, 1);
  314.     PtoCstr((char *)resString);
  315.     if ( strcmp("", (char *)resString) == 0 ) {
  316. /* i.e. have a resource fork but not a soundfile resource. Check for a SD2 resource */
  317.         myHndl = GetResource('STR ', SAMPLE_RATE_RES );
  318.         if ( myHndl && (theErr = ResError()) == noErr) {
  319.             aString = (StringHandle)GetString(SAMPLE_RATE_RES);
  320.             HLock(aString);
  321.             PstringCopy((char *)myString, (char *)*aString);
  322.             PtoCstr((char *)myString);
  323.             /* "cast" to integer value */
  324.             i = strcspn((char *)myString, ".");
  325.             if ( i > 0 )
  326.                 myString[i] = '\0';
  327.             CtoPstr((char *)myString);
  328.             StringToNum(myString, &SampleRate);
  329.             HUnlock(aString);
  330.             DisposHandle(aString);
  331.             SoundFileType = SD2;
  332.             myHndl = GetResource('STR ', SAMPLE_CHANNELS_RES );
  333.             if ((theErr = ResError()) == noErr) {
  334.                 aString = (StringHandle)GetString(SAMPLE_CHANNELS_RES);
  335.                 HLock(aString);
  336.                 StringToNum(*aString, &NumChannels);
  337.                 HUnlock(aString);
  338.             }
  339.             DisposHandle(aString);
  340.             DisposHandle(myHndl);
  341.         }
  342.         else {
  343.         /* not a SF resource and not a SD2 resource, could be an Alchemy AIFF file with resources */
  344.             if (SoundFileType != AIFF) {
  345.                 SDnoResource = TRUE;
  346.                 return(TRUE);
  347.             }
  348.             else {
  349.                 CtoPstr((char *)resString);
  350.                 OSError2("\pUnknown Sound file type", resString, NIL);
  351.                 return(FALSE);
  352.             }
  353.         }
  354.     }
  355. /* we may have a SF resource, as well as other resources */
  356.     if ( strcmp("FLOAT", (char *)resString) == 0 ) {
  357.         SoundFileType = FLOAT;
  358.     }
  359.     else if ( strcmp("INT16", (char *)resString) == 0 ) {
  360.         SoundFileType = INT16;
  361.     }
  362.     else if ( strcmp("SD", (char *)resString) == 0 ) {
  363.         SoundFileType = SD1;
  364.     }
  365.     else if ( strcmp("SD1", (char *)resString) == 0 ) {
  366.         SoundFileType = SD1;
  367.     }
  368.     else if ( strcmp("SD2", (char *)resString) == 0 ) {
  369.         SoundFileType = SD2;
  370.     }
  371.     else if ( strcmp("AIFF", (char *)resString) == 0 ) {
  372.         SoundFileType = AIFF;
  373.     }
  374.  
  375.     GetIndString(&resString, SFRESOURCENUM, 2);
  376.     if ( resString[0] > 0 ) {
  377.         StringToNum(resString, &NumChannels);
  378.         if ( NumChannels > 4L) {
  379.             OSError("\pmono, stereo or quad soundfiles", NIL);
  380.             return(FALSE);
  381.         }
  382.         if ( NumChannels < 1 ) {
  383.     /*            OSError2("\pNumber of channels = 0 ?", "mono assumed", NIL);*/
  384.             NumChannels = 1;
  385.         }
  386.     }
  387.  
  388.     GetIndString(&resString, SFRESOURCENUM, 3);
  389.     if ( resString[0] > 0 ) {
  390.         StringToNum(resString, &SampleRate);
  391.     }
  392.     GetIndString(&resString, SFRESOURCENUM, 4);
  393.     if ( resString[0] > 0 ) {
  394.         PtoCstr((char *)resString);
  395.         sscanf((char *)resString, "%lf", &MaxSample);
  396.     }
  397.     GetIndString(&resString, SFRESOURCENUM, 5);
  398.     if ( resString[0] > 0 ) {
  399.         PtoCstr((char *)resString);
  400.         sscanf((char *)resString, "%lf", &MinSample);
  401.     }
  402.     CloseResFile(sfResFileRefNum);
  403.  
  404.     return(TRUE);
  405. }
  406.  
  407.  
  408.  
  409. Boolean    CloseSF()
  410. {
  411.     extern        ioParam        myIOParmBlk;
  412.     extern        ioParam        NewParmBlk;
  413.     extern    int    IFileOpen, OFileOpen;
  414.     
  415.     if ( IFileOpen ) {
  416.         if ( (theErr = PBClose(&myIOParmBlk, FALSE)) != noErr ) { 
  417.             OSError2("\pError closing Sound File: ", &SoundFileName, theErr);
  418.             return(FALSE);
  419.         }
  420.         fPB.ioCompletion = (ProcPtr)NIL;
  421.         fPB.ioNamePtr = myIOParmBlk.ioNamePtr;
  422.         fPB.ioVRefNum = myIOParmBlk.ioVRefNum;
  423.         fPB.ioFVersNum = myIOParmBlk.ioVersNum;
  424.         fPB.ioFDirIndex = NIL;
  425.         if ( (theErr =     PBFlushVol(&fPB, FALSE)) != noErr ) { 
  426.             OSError2("\pError returned from PBFlushVol for sample file's volume: ", "", theErr);
  427.             return(FALSE);
  428.         }
  429.     }
  430.     
  431.     if ( OFileOpen ) {
  432.         if ( (theErr = PBClose(&NewParmBlk, FALSE)) != noErr ) { 
  433.             OSError2("\pError closing Sound File: ", &SoundFileName, theErr);
  434.             return(FALSE);
  435.         }
  436.         fPB.ioCompletion = (ProcPtr)NIL;
  437.         fPB.ioNamePtr = NewParmBlk.ioNamePtr;
  438.         fPB.ioVRefNum = NewParmBlk.ioVRefNum;
  439.         fPB.ioFVersNum = NewParmBlk.ioVersNum;
  440.         fPB.ioFDirIndex = NIL;
  441.         if ( (theErr =     PBFlushVol(&fPB, FALSE)) != noErr ) { 
  442.             OSError2("\pError returned from PBFlushVol for sample file's volume: ", "", theErr);
  443.             return(FALSE);
  444.         }
  445.     }
  446.     return(TRUE);
  447. }
  448.  
  449.  
  450. Boolean    SetSFDir(DirName, theDirID)
  451.     Str255        DirName;
  452.     long        *theDirID;
  453. {
  454.     extern        int            SFSaveVRef;
  455.     extern        int            ReportFileRefNum;
  456.     Str255        aString;
  457.     
  458.     
  459.     PstringCopy((char *)aString, DirName);
  460.     myWDParamBlk.ioNamePtr = (StringPtr)aString;
  461.     myWDParamBlk.ioCompletion = NIL;
  462.     myWDParamBlk.ioVRefNum = 0;
  463.     myWDParamBlk.ioWDDirID = NIL;
  464.  
  465.     if ( (theErr = PBHSetVol(&myWDParamBlk, FALSE)) != noErr ) {
  466. /*        OSError2("\pSetSFDir error: PBHSetVol", myWDParamBlk.ioNamePtr, (long)theErr);
  467.         return(FALSE);
  468. */
  469.     }
  470.     
  471.     PBHGetVol(&myWDParamBlk, FALSE);
  472.  
  473.     *theDirID = myWDParamBlk.ioWDDirID;
  474.     CurDirStore = *theDirID;
  475.     
  476.     SFSaveVRef = myWDParamBlk.ioVRefNum;
  477.     SFSaveDisk = -1 * SFSaveVRef;
  478.     return(TRUE);
  479. }
  480.  
  481.  
  482.  
  483. Boolean    GetSFDir(DirName)
  484.     Str255    *DirName;
  485. {
  486.     Str255        myStr;
  487.     WDPBRec        myWDParamBlk;
  488.     DirInfo        myCatInfoBlk;
  489.     
  490.     myCatInfoBlk.ioCompletion = NIL;
  491.     myCatInfoBlk.ioVRefNum = -SFSaveDisk;
  492.     myCatInfoBlk.ioDrDirID = CurDirStore;
  493.     myCatInfoBlk.ioFDirIndex = -1;
  494.     myCatInfoBlk.ioNamePtr = (StringPtr)myStr;
  495.     if ( (theErr = PBGetCatInfo(&myCatInfoBlk, FALSE)) != noErr ) {
  496.         OSError2("\pPBGetCatInfo", myCatInfoBlk.ioNamePtr, (long)theErr);
  497.         return(FALSE);
  498.     }
  499.     
  500.     PstringCopy(DirName, (char *)myStr);
  501.     PstringCat(DirName, "\p:");
  502.     
  503.     while (myCatInfoBlk.ioDrDirID != 2 ) {
  504.         myCatInfoBlk.ioDrDirID = myCatInfoBlk.ioDrParID;
  505.         if ( (theErr = PBGetCatInfo(&myCatInfoBlk, FALSE)) != noErr ) {
  506.             OSError2("\pPBGetCatInfo", myCatInfoBlk.ioNamePtr, (long)theErr);
  507.             return(FALSE);
  508.         }
  509.         PstringCat((char *)myStr, "\p:");
  510.         PstringCat((char *)myStr, DirName);
  511.         PstringCopy(DirName, (char *)myStr);
  512.     }
  513.     CurDirStore = myCatInfoBlk.ioDrDirID;
  514.     
  515.     return(TRUE);
  516. }
  517.  
  518.  
  519.  
  520.  
  521.  
  522. typedef    struct {
  523.     int                    nstrings;
  524.     Str255        theStrings;
  525. } ResDatum;
  526.  
  527. Boolean    updateNewSFResFile()
  528. {    
  529.     ResDatum                **newSfRes;
  530.     StringHandle            myStringHandle0, myStringHandle1, myStringHandle2, myStringHandle3;
  531.     StringPtr        strptr;
  532.     Str255                myString;
  533.     extern        int            SoundFileType;
  534.     extern        int        SFOUTPUTtype;
  535.     extern        long            NumChannels;
  536.     extern        double        MaxSample;
  537.     extern        double        MinSample;
  538.     extern        long            SampleRate;
  539.     int                    NsfResFileRefNum;
  540.     int                    i;
  541.     
  542.     /* open the resource fork */
  543.     CreateResFile(NewSoundFileName);
  544.     if ( ( theErr = ResError()) != noErr ) {
  545.         OSError2("\pOpenSFWrite: CreateResFile error: ", NewSoundFileName, theErr);
  546.         return(FALSE);
  547.     }
  548.     
  549.     NsfResFileRefNum = OpenResFile(NewSoundFileName);
  550.     if ( ( theErr = ResError()) != noErr ) {
  551.         OSError2("\pupdateNewSFResFile: OpenResFile error: ", NewSoundFileName, theErr);
  552.         return(FALSE);
  553.     }
  554.  
  555.     newSfRes = (ResDatum **) NewHandle(sizeof(ResDatum));
  556.     HLock(newSfRes);
  557.     
  558.     (**newSfRes).nstrings = 5;
  559.  
  560.     strptr = (*newSfRes)->theStrings;
  561.     
  562.     switch(SFOUTPUTtype) {
  563.         case    INT16:
  564.             PstringCopy(strptr, "\pINT16");
  565.             strptr += (*strptr) + 1;
  566.             break;
  567.         case    AIFF:
  568.             PstringCopy(strptr, "\pAIFF");
  569.             strptr += (*strptr) + 1;
  570.             break;
  571.         case    SD1:
  572.             PstringCopy(strptr, "\pSD");
  573.             strptr += (*strptr) + 1;
  574.             break;
  575.         case    SD2:
  576.             PstringCopy(strptr, "\pSD2");
  577.             strptr += (*strptr) + 1;
  578.             break;
  579.         case    FLOAT:
  580.             PstringCopy(strptr, "\pFLOAT");
  581.             strptr += (*strptr) + 1;
  582.             break;
  583.         default:
  584.             PstringCopy(strptr, "\pINT16");
  585.             strptr += (*strptr) + 1;
  586.             break;
  587.     }
  588.     
  589.     
  590.     if ( NumChannels < 1 )
  591.         NumChannels = 1;
  592.     NumToString(NumChannels, &myString);
  593.     PstringCopy(strptr, (char *)myString);
  594.     strptr += (*strptr) + 1;
  595.  
  596.     NumToString(SampleRate, &myString);
  597.     PstringCopy(strptr, (char *)myString);
  598.     strptr += (*strptr) + 1;
  599.     
  600.     i = sprintf((char *)myString, "%lf", (double)MaxSample);
  601.     CtoPstr((char *)myString);
  602.     PstringCopy(strptr, (char *)myString);
  603.     strptr += (*strptr) + 1;
  604.     
  605.     i = sprintf((char *)myString, "%lf", (double)MinSample);
  606.     CtoPstr((char *)myString);
  607.     PstringCopy(strptr, (char *)myString);
  608.  
  609.     
  610.     AddResource(newSfRes, 'STR#', SFRESOURCENUM, "\pSF params");
  611.     if ((theErr = ResError()) != noErr) {
  612.         OSError2("\pAddResource error in updateNewSFResFile()", NIL, theErr);
  613.         HUnlock(newSfRes);
  614.         DisposHandle(newSfRes);
  615.         return(FALSE);
  616.     }
  617.     ChangedResource(newSfRes);
  618.     if ( (theErr = ResError()) != noErr ) {
  619.         OSError2("\pChangedResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  620.         HUnlock(newSfRes);
  621.         DisposHandle(newSfRes);
  622.         return(FALSE);
  623.     }
  624.     WriteResource(newSfRes);
  625.     if ( (theErr = ResError()) != noErr ) {
  626.         OSError2("\pWriteResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  627.         HUnlock(newSfRes);
  628.         DisposHandle(newSfRes);
  629.         return(FALSE);
  630.     }
  631.     
  632.     
  633.     /*add SD2 resources */
  634.     if ( SFOUTPUTtype == SD2 ) {
  635.         myStringHandle1 = (StringHandle)NewHandle(sizeof(StringHandle));
  636.         i = sprintf((char *)myString, "%d", (int)NumChannels);
  637.         CtoPstr((char *)myString);
  638.         SetString(myStringHandle1, myString);
  639.         HLock((Handle)myStringHandle1);
  640.         AddResource((Handle)myStringHandle1, 'STR ', SAMPLE_CHANNELS_RES, "\pchannels");
  641.         HUnlock((Handle)myStringHandle1);
  642.         
  643.         ChangedResource((Handle)myStringHandle1);
  644.         if ( (theErr = ResError()) != noErr ) {
  645.             OSError2("\pChangedResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  646.             HUnlock((Handle)myStringHandle1);
  647.             DisposHandle((Handle)myStringHandle1);
  648.             return(FALSE);
  649.         }
  650.         WriteResource((Handle)myStringHandle1);
  651.         if ( (theErr = ResError()) != noErr ) {
  652.             OSError2("\pWriteResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  653.             HUnlock((Handle)myStringHandle1);
  654.             DisposHandle((Handle)myStringHandle1);
  655.             return(FALSE);
  656.         }
  657.  
  658.         myStringHandle2 = (StringHandle)NewHandle(sizeof(StringHandle));
  659.         i = sprintf((char *)myString, "%ld", (long)SampleRate);
  660.         CtoPstr((char *)myString);
  661.         SetString(myStringHandle2, myString);
  662.         HLock((Handle)myStringHandle2);
  663.         AddResource((Handle)myStringHandle2, 'STR ', SAMPLE_RATE_RES, "\psample-rate");
  664.         HUnlock((Handle)myStringHandle2);
  665.  
  666.         ChangedResource((Handle)myStringHandle2);
  667.         if ( (theErr = ResError()) != noErr ) {
  668.             OSError2("\pChangedResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  669.             HUnlock((Handle)myStringHandle2);
  670.             DisposHandle((Handle)myStringHandle2);
  671.             return(FALSE);
  672.         }
  673.         WriteResource((Handle)myStringHandle2);
  674.         if ( (theErr = ResError()) != noErr ) {
  675.             OSError2("\pWriteResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  676.             HUnlock((Handle)myStringHandle2);
  677.             DisposHandle((Handle)myStringHandle2);
  678.             return(FALSE);
  679.         }
  680.  
  681.  
  682.  
  683.         myStringHandle3 = (StringHandle)NewHandle(sizeof(StringHandle));
  684.         SetString(myStringHandle3, "\p2");
  685.         HLock((Handle)myStringHandle3);
  686.         AddResource((Handle)myStringHandle3, 'STR ', SAMPLE_SIZE_RES, "\psample-size");
  687.         HUnlock((Handle)myStringHandle3);
  688.  
  689.         if ((theErr = ResError()) != noErr) {
  690.             OSError2("\pAddResource error in updateNewSFResFile()", NIL, theErr);
  691.             HUnlock((Handle)myStringHandle3);
  692.             DisposHandle((Handle)myStringHandle3);
  693.             return(FALSE);
  694.         }
  695.         ChangedResource((Handle)myStringHandle3);
  696.         if ( (theErr = ResError()) != noErr ) {
  697.             OSError2("\pChangedResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  698.             HUnlock((Handle)myStringHandle3);
  699.             DisposHandle((Handle)myStringHandle3);
  700.             return(FALSE);
  701.         }
  702.         WriteResource((Handle)myStringHandle3);
  703.         if ( (theErr = ResError()) != noErr ) {
  704.             OSError2("\pWriteResource error in updateNewSFResFile()", NewSoundFileName, theErr);
  705.             HUnlock((Handle)myStringHandle3);
  706.             DisposHandle((Handle)myStringHandle3);
  707.             return(FALSE);
  708.         }
  709.         HUnlock((Handle)myStringHandle3);
  710.         DisposHandle((Handle)myStringHandle1);
  711.         DisposHandle((Handle)myStringHandle2);
  712.         DisposHandle((Handle)myStringHandle3);
  713.         
  714.     }
  715.     CloseResFile(NsfResFileRefNum);
  716.     if ( (theErr = ResError()) != noErr ) {
  717.         OSError2("\pCloseResFile error in updateNewSFResFile()", NewSoundFileName, theErr);
  718.         return(FALSE);
  719.     }
  720.     if ( (theErr = ResError()) != noErr ) {
  721.          OSError2("\pUseResFile error in updateNewSFResFile()", NewSoundFileName, theErr);
  722.         return(FALSE);
  723.     }
  724.     PBFlushVol(&fPB, FALSE);
  725.     return(TRUE);
  726. }
  727.  
  728.  
  729.  
  730. void GetMusic4C_Prefs()
  731. {
  732.     int            refNum;
  733.     StringPtr    volName;
  734.     char        buffer[2];
  735.     long        count;
  736.     Str255        FileFormat;
  737.     extern        Str255        SFDirectoryName;
  738.     extern        SysEnvRec    SysEnvData;
  739.     int    i;
  740.     
  741. /* "Music4C_Prefs" is kept in the System Folder */
  742.     SFDirectoryName[0] = 0;
  743.     theErr = FSOpen("\pMusic4C_Prefs", SysEnvData.sysVRefNum, &refNum);
  744.     if (theErr == noErr) {
  745.         count = 2L;
  746.         theErr = FSRead (refNum, &count, &buffer);
  747.         if ( theErr != noErr ) {
  748.             OSError("\pError reading Preferences file", NIL);
  749.         }
  750.         count = sizeof(FileFormat);
  751.         theErr = FSRead (refNum, &count, &FileFormat);
  752.         if ( theErr != noErr ) {
  753.             OSError("\pError reading Preferences file", NIL);
  754.         }
  755.         count = sizeof(SFDirectoryName);
  756.         theErr = FSRead (refNum, &count, &SFDirectoryName);
  757.         if ( theErr != noErr ) {
  758.             OSError("\pError reading Preferences file", NIL);
  759.         }
  760.         theErr = FSClose(refNum);
  761.     }
  762. }
  763.